import { math, sp, v2 } from "cc";
import GameSingle from "../GameSingle";
import { BaseBulletComp } from "../bullet/BaseBulletComp";
import { BaseFightLogic } from "../core/BaseFightLogic";
import BaseAction from "../core/strategy/BaseAction";
import IFightFilter from "../core/strategy/IFightFilter";

/*****************************
 *@file: SimpleShootAttack
 *@author: 陈吕唐
 *@desc: 发射子弹进行攻击
 *@date: 2024-03-08	14:43
 *****************************/
export default class SimpleShootAttack extends BaseAction {
    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /**
     * @description: 找到敌人策略
     */
    private _find: IFightFilter = undefined!;
    /***************************************************************
     *PropertyUI 引用的控件
     ***************************************************************/
    private spine: sp.Skeleton = undefined!;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    /**
     * 
     * @param value 行动的战斗单位
     * @param spine 动画组件
     * @param bulletPrefab 子弹预制体
     * @param bulletParent 
     */
    public constructor(value: BaseFightLogic, spine: sp.Skeleton) {
        super(value);
        this.spine = spine;
    }
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    /**
     * 简单发射子弹攻击
     * @returns 
     */
    public async action(): Promise<boolean> {

        let source = this.fight;
        /**
         * 当前选中敌人
         */
        let enemies: BaseFightLogic[] = this.find.filter(source.enemy);
        if (enemies.length <= 0) {
            return false;
        }

        await this.playNormalAnimation();

        let bullet = this.createNormalBullet(source);
        let bulletNode = GameSingle.single.getBulletNode(bullet);

        this.fight.node.addChild(bulletNode);

        let comp = bulletNode.getComponent(BaseBulletComp);
        let enemy = enemies[0];
        comp.setLinearVelocity(this.shootLinearVelocity(enemy));
        return true;
    }

    /**
     * 计算子弹发射方向
     * @param enemy 
     */
    public shootLinearVelocity(enemy: BaseFightLogic): math.Vec2 {
        let ePos = enemy.node.getWorldPosition();
        let mPos = this.fight.node.getWorldPosition();
        let v = v2(ePos.x - mPos.x, ePos.y - mPos.y);
        return v
    }
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/
    /**
     * 播放攻击动画
     * @returns 
     */
    private playNormalAnimation(): Promise<void> {
        let promise: Promise<void> = new Promise<void>((resolve, reject) => {
            this.spine.setAnimation(0, "attack_01", false);
            this.spine.setCompleteListener(() => {
                resolve();
            });
            this.spine.setInterruptListener(() => {
                resolve();
            });
        });
        return promise;
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/
    protected get find(): IFightFilter {
        if (!this._find) {
            this._find = this.createDefaultFind();
        }
        return this._find;
    }

    protected set find(value: IFightFilter) {
        this._find = value;
    }
}